/* this class serve to create the function: "Display" something to standard output.
 * make itself a 'base class' to provide a base function of "display something". 
 * the role of the class can be describe as:
 * -> the base class of "Display"
 * -> at the top of functionality layer of class hierarchy
 */

#ifndef DISPLAY_H
#define DISPLAY_H
#include "implement_layer/DisplayImpl.h"

namespace FuncLayer
{
class Display
{
  private:
    /* The Bridge
     * this pointer connects 'function Layer' and 'implement layer'
     * we can change the final output of "Display" by accepting different impls
    */
    ImplLayer::DisplayImpl* pimpl;

  public:

    Display(ImplLayer::DisplayImpl* i): pimpl(i){}

    /* we use delegation to decouple the abstraction(Display) from its implementation:
     * as shown in the 3 functions below, 'Display' simply delegates the 'open', 
     * 'print' and 'close' operations to the Impl layer, THIS ALLOWS US TO SWITCH IMPLS
     * WITHOUT MODIFYING THE Display CLASS, making it compatible with any implementataion,
     * not just 'StringDisplayImpl'
    */
    void open();

    void print();

    void close();

    void display();
};
}; // namespace FuncLayer
#endif
